/**
 * Copyright (c) 2020 Coder League
 * All rights reserved.
 *
 * File：FunctionDaoImpl.java
 * History:
 *         2020年12月20日: Initially created, Chrise.
 */
package club.coderleague.cfss.dao.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import club.coderleague.cfss.dao.extension.FunctionDaoExtension;
import club.coderleague.cfss.domain.beans.UserSession;
import club.coderleague.cfss.domain.entities.Functions;
import club.coderleague.cfss.domain.enums.EntityState;
import club.coderleague.cfss.domain.enums.FuncType;
import club.coderleague.cfss.domain.enums.UserType;
import club.coderleague.cfss.util.HttpServletUtil;
import club.coderleague.data.jpa.id.support.SnowflakeV4;
import club.coderleague.data.jpa.repository.support.AbstractDataRepositoryExtension;

/**
 * 功能数据访问对象实现。
 * @author Chrise
 */
public class FunctionDaoImpl extends AbstractDataRepositoryExtension<Functions, Long, SnowflakeV4> implements FunctionDaoExtension {
	/**
	 * @see club.coderleague.cfss.dao.extension.FunctionDaoExtension#findAuthorizationByParentfuncAndFunctype(java.lang.Long, java.util.List)
	 */
	@Override
	public List<Functions> findAuthorizationByParentfuncAndFunctype(Long parentfunc, List<Integer> functype) {
		StringBuilder jpqlBuilder = new StringBuilder("from Functions f where f.entitystate = :validstate");
		Map<String, Object> params = new HashMap<>();
		params.put("validstate", EntityState.VALID.getValue());
		if (parentfunc != null) {
			jpqlBuilder.append(" and f.parentfunc = :parentfunc");
			params.put("parentfunc", parentfunc);
		}
		if (functype != null && !functype.isEmpty()) {
			jpqlBuilder.append(" and f.functype in (:functype)");
			params.put("functype", functype);
		}
		// 获取用户信息
		UserSession us = HttpServletUtil.getUserSession();
		if (!UserType.ADMIN.equalsValue(us.getUsertype())) {
			jpqlBuilder.append(" and exists(select 1 from Users u"
				+ " inner join Userauths ua on ua.entitystate = :validstate and ua.userid = u.entityid"
				+ " inner join Roles r on r.entitystate = :validstate and r.entityid = ua.roleid"
				+ " inner join Roleauths ra on ra.entitystate = :validstate and ra.roleid = r.entityid"
				+ " inner join Functions fa on fa.entitystate = :validstate and fa.entityid = ra.funcid"
				+ " where u.entityid = :userid and fa.entityid = f.entityid)");
			params.put("userid", us.getUserid());
		}
		jpqlBuilder.append(" order by functype asc, showorder asc");
		return super.queryEntityList(jpqlBuilder.toString(), params);
	}
	
	/**
	 * @see club.coderleague.cfss.dao.extension.FunctionDaoExtension#getFuncMgrListDao(java.util.Map)
	 */
	@Override
	public List<Map<String, Object>> getFuncMgrListDao(Map<String, Object> params) {
		Map<String, Object> param = new HashMap<String, Object>();
		String sql = "select entityid, funcname, parentfunc, functype, showicon, invokemethod, rightsupport, funcdesc, showorder, entitystate from Functions where entitystate = :entitystate ";
		boolean isrecycle = Boolean.valueOf((String) params.get("isrecycle"));
		int entitystate = !isrecycle ? EntityState.VALID.getValue() : EntityState.INVALID.getValue();
		param.put("entitystate", entitystate);
		if (params.get("keyword") != null && StringUtils.isNotBlank(params.get("keyword").toString())) {
			sql += "and (funcname like :funcname or invokemethod like :invokemethod) ";
            param.put("funcname", "%" + (String) params.get("keyword") + "%");
            param.put("invokemethod", "%" + (String) params.get("keyword") + "%");
        }
		
		sql += "order by showorder ";
		return super.queryMapListBySql(sql, param);
	}
	
	/**
	 * @see club.coderleague.cfss.dao.extension.FunctionDaoExtension#getParentFuncSelectListDao()
	 */
	@Override
	public List<Map<String, Object>> getParentFuncSelectListDao() {
		String sql = "select entityid, funcname, parentfunc from Functions where functype != ?0 and entitystate = ?1";
		return super.queryMapListBySql(sql, FuncType.BUTTON.getValue(), EntityState.VALID.getValue());
	}
	
	/**
	 * @see club.coderleague.cfss.dao.extension.FunctionDaoExtension#getRepeatDataByFuncNameOrParentFuncOrFuncTypeDao(java.lang.String, java.lang.Long, java.lang.Integer, java.lang.Long)
	 */
	@Override
	public Boolean getRepeatDataByFuncNameOrParentFuncOrFuncTypeDao(String funcname, Long parentfunc, Integer functype, Long entityid) {
		Map<String, Object> param = new HashMap<>();
		String sql = "select count(entityid) from Functions where funcname = :funcname and functype = :functype and entitystate = :entitystate ";
		param.put("funcname", funcname);
		param.put("functype", functype);
		param.put("entitystate", EntityState.VALID.getValue());
		if (parentfunc != null && parentfunc != -1) {
			sql += "and parentfunc = :parentfunc ";
			param.put("parentfunc", parentfunc);
		} else sql += "and parentfunc is null ";
		
		if (entityid != null) {
			sql += "and entityid != :entityid ";
			param.put("entityid", entityid);
		}
		
		Long count = super.queryLong(sql, param);
		return (count > 0);
	}
	
	/**
	 * @see club.coderleague.cfss.dao.extension.FunctionDaoExtension#getFunctionsDetailDataByFuncidDao(java.lang.String)
	 */
	@Override
	public Map<String, Object> getFunctionsDetailDataByFuncidDao(String entityid) {
		String sql = "select f1.entityid, f1.funcname, f2.funcname as parentfunc, f1.functype, f1.showicon, f1.invokemethod, f1.rightsupport, f1.funcdesc, f1.showorder from Functions f1 left join Functions f2 on f1.parentfunc = f2.entityid and f2.entitystate = ?0 where f1.entityid = ?1 ";
		return super.queryMapBySql(sql, EntityState.VALID.getValue(), entityid);
	}
}
